package com.geek.water.job;


import com.geek.water.constant.RedisImgConstant;
import com.geek.water.service.impl.FileUploadContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Set;

/**
 * @author chenmin
 * @desc 清理垃圾图片的定时任务
 * @date 2025/8/6
 */
@Slf4j
@RequiredArgsConstructor
public class CleanImgJob extends QuartzJobBean {

    private final RedisTemplate<String,Object> redisTemplate;
    private final FileUploadContext fileUploadContext;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.info("=================== 开始执行清理垃圾图片定时任务 CleanImgJob ===================");
        log.info("任务开始时间: {}", LocalDateTime.now());

        try {
            // 获取所有上传的图片
            Set<Object> allUploadedPics = redisTemplate.opsForSet().members(RedisImgConstant.UPLOAD_PIC);
            // 获取数据库中已保存的图片
            Set<Object> dbSavedPics = redisTemplate.opsForSet().members(RedisImgConstant.UPLOAD_DB_PIC);

            log.info("所有上传的图片数量: {}", allUploadedPics != null ? allUploadedPics.size() : 0);
            log.info("数据库中已保存的图片数量: {}", dbSavedPics != null ? dbSavedPics.size() : 0);

            // 计算垃圾图片（差集：上传的图片 - 数据库中已保存的图片）
            Set<Object> garbagePics = redisTemplate.opsForSet().difference(RedisImgConstant.UPLOAD_PIC, RedisImgConstant.UPLOAD_DB_PIC);

            if (CollectionUtils.isEmpty(garbagePics)) {
                log.info("没有发现垃圾图片，任务结束");
                return;
            }

            log.info("发现垃圾图片数量: {}", garbagePics.size());

            int successCount = 0;
            int failCount = 0;

            for (Object picUrl : garbagePics) {
                try {
                    String url = (String) picUrl;
                    log.info("正在处理垃圾图片: {}", url);

                    // 获取当前图片所存储的云服务商信息
                    Object providerObj = redisTemplate.opsForValue().get(url + "_provider");
                    if (providerObj == null) {
                        log.warn("图片 {} 没有找到云服务商信息，跳过处理", url);
                        failCount++;
                        continue;
                    }

                    String provider = providerObj.toString();
                    log.info("图片 {} 的云服务商: {}", url, provider);

                    // 删除图片
                    boolean deleteSuccess = fileUploadContext.delete(url, provider);
                    if (deleteSuccess) {
                        // 删除成功后，清理Redis中的相关记录
                        redisTemplate.delete(url + "_provider");
                        redisTemplate.opsForSet().remove(RedisImgConstant.UPLOAD_PIC, url);
                        successCount++;
                        log.info("成功删除垃圾图片: {}, 云服务商: {}", url, provider);
                    } else {
                        failCount++;
                        log.error("删除垃圾图片失败: {}, 云服务商: {}", url, provider);
                    }
                } catch (Exception e) {
                    failCount++;
                    log.error("处理垃圾图片时发生异常: {}", picUrl, e);
                }
            }

            log.info("垃圾图片清理完成 - 成功: {}, 失败: {}, 总计: {}", successCount, failCount, garbagePics.size());

        } catch (Exception e) {
            log.error("执行清理垃圾图片定时任务时发生异常", e);
            throw new JobExecutionException("清理垃圾图片任务执行失败", e);
        }

        log.info("=================== 清理垃圾图片定时任务 CleanImgJob 执行完成 ===================");
        log.info("任务结束时间: {}", LocalDateTime.now());
    }
}
